﻿using LdtJudge.DataEngine.Common.DataSave;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.Data.DataParseStorage;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.ConfigModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.CommonModule.CourtCountGenerate
{
    /// <summary>
    /// 庭次推导
    /// </summary>
    public class CourtNoDeduce
    {
        

        /// <summary>
        /// 上下文对象
        /// </summary>
        public DataContext dataContext { get; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dataContextin"></param>
        public CourtNoDeduce(DataContext dataContextin) 
        {
            dataContext = dataContextin;
        }

        /// <summary>
        /// 获取开庭次数或是开庭时间
        /// </summary>
        /// <param name="elementDatas">提取节点结合</param>
        /// <param name="attributeName">属性名称</param>
        /// <returns></returns>
        private string GetCurrentCourtAttribute(List<SD_ElementDataModel> elementDatas, string attributeName)
        {
            try
            {
                List<SD_ElementDataModel> re = new List<SD_ElementDataModel>();
                re = elementDatas.Where(a => a.ED_XmlPath == "案件信息要素中心/审判/一审/庭审阶段/庭审详情/法庭使用记录/法庭使用详情/@" + attributeName).ToList();
                if (re.Count == 0)
                {
                    return null;
                }
                else
                {
                    return re[0].ED_ExtValue;
                }
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("CourtNoDeduce:GetCurrentCourtAttribute  获取" + attributeName + "属性值报错" + ex.Message, LogMessageType.Error);
                return null;
            }

        }

        private string GetCurrentCourtAttribute(List<DataModel> elementDatas, string attributeName, TtargetDataConfig typedReference)
        {
            try
            {
                    DataModel dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(elementDatas, "", typedReference.Xmlpath); ;
                    if (dataModel.AttributesList.FirstOrDefault(a => a.Name == attributeName) != null)
                    {
                        return dataModel.AttributesList.FirstOrDefault(a => a.Name == attributeName).sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                    }
                

                return null;
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("CourtNoDeduce:GetCurrentCourtAttribute  获取" + attributeName + "属性值报错" + ex.Message, LogMessageType.Error);
                return null;
            }

        }
        /// <summary>
        /// 推导开庭次数
        /// </summary>
        /// <param name="elementDatas">提取节点结合</param>
        /// <param name="caseOnlyID">案件唯一ID</param>
        /// <returns>开庭次数</returns>
        public string DeduceCourtNo(List<DataModel> elementDatas, string caseOnlyID, TtargetDataConfig typedReference)
        {
            // 返回值
            string re = string.Empty;
            try
            {
                // 获取当前分析出的庭次和开庭时间
                string courtNo = GetCurrentCourtAttribute(elementDatas, typedReference.Number, typedReference);
                if (string.IsNullOrEmpty(courtNo))
                {
                    dataContext.InteractiveShow.LogShow("--------------------当前文本中为提取出庭次，开始获取开庭时间---------------");
                    string courtDate = GetCurrentCourtAttribute(elementDatas, typedReference.OpeningTime, typedReference);
                    if (!string.IsNullOrEmpty(courtDate))
                    {
                        dataContext.InteractiveShow.LogShow("当前文本提取到的开庭时间:" + courtDate);
                        // 获取数据库的庭次和开庭时间ID
                        // 返回的结构<庭次,EDID:开庭时间>
                        dataContext.InteractiveShow.LogShow("----------------------获取数据库中当前案件的庭次和开庭时间-----------------------");
                        var historyCourtDataNO = GetHistoryCourtDateNO(caseOnlyID, out List<DataModel> lastresultmodelist,typedReference);
                        if (historyCourtDataNO.Count() == 0)
                        {
                            dataContext.InteractiveShow.LogShow("数据库中无当前案件的庭次和开庭时间，推导本次开庭的庭次为第一次。");
                            // 如果数据库中没有庭次那么就认为当前是第一次开庭
                            // 推导生成新的庭次
                            re = "N:1";
                        }
                        else
                        {
                            dataContext.InteractiveShow.LogShow("------数据库中存在当前案件以往庭次和开庭时间，开始比对当前文本的开庭时间与以往的开庭时间从而推导庭次------");
                            // 将提取到的当前文本的开庭时间转化成datetime类型，备下面比较实用
                            DateTimeFormatInfo dtFormat = new DateTimeFormatInfo();
                            dtFormat.ShortDatePattern = "yyyy-MM-dd HH:mm:ss";
                            DateTime extCourtDate = Convert.ToDateTime(courtDate, dtFormat);
                            // 遍历数据库中的开庭时间，并与提取到的当前文本的开庭时间比较
                            string compareResult = string.Empty;
                            // 数据库中第一条记录的庭次
                            string firstCourtNo = string.Empty;
                            //遍历时，记录上一次的庭次
                            string lastCourtNO = string.Empty;
                            foreach (var keyValuePair in historyCourtDataNO)
                            {
                                dataContext.InteractiveShow.LogShow("数据中的庭次:" + keyValuePair.Key + " 开庭时间:" + keyValuePair.Value.Item2 + "===当前文本中的开庭时间:" + dtFormat);
                                // 本次比较的结果，当前文本提取的开庭日期小于本次遍历的开庭日期，这个compareFlag=min，否则compareFlag=max
                                string compareFlag = string.Empty;
                                // 获取本次遍历的开庭时间
                                if (!string.IsNullOrEmpty(keyValuePair.Value.Item2))
                                {
                                    // 比较
                                    DateTime dt = Convert.ToDateTime(keyValuePair.Value.Item2, dtFormat);
                                    int comparentR = DateTime.Compare(extCourtDate, dt);
                                    if (comparentR < 0)
                                    {
                                        compareFlag = "min";
                                    }
                                    else
                                    {
                                        compareFlag = "max";
                                    }
                                    // 第一遍历时将本次比较结果作为最终比较结果
                                    if (string.IsNullOrEmpty(compareResult))
                                    {
                                        compareResult = compareFlag;
                                        firstCourtNo = keyValuePair.Key;
                                    }
                                    else
                                    {
                                        // 非第一次遍历需要比对上一次结果与本次比对结果，如上次是man，这次是mix，说明当前的开庭时间在二者之间，对应庭次也在二者之间
                                        if (compareFlag != compareResult)
                                        {
                                            if (compareFlag == "min")
                                                re = "N:" + Convert.ToString(Convert.ToInt32(lastCourtNO) - 1);
                                            if (compareFlag == "max")
                                                re = "N:" + Convert.ToString(Convert.ToInt32(lastCourtNO) + 1);
                                            dataContext.InteractiveShow.LogShow("经过比对当前的开庭时间处于已有庭次的中间位置，推导出新的新的庭次" + re);
                                            if (Math.Abs(Convert.ToInt32(keyValuePair.Key) - Convert.ToInt32(lastCourtNO)) == 1)
                                            {
                                                dataContext.InteractiveShow.LogShow("需要更新数据库中原有的庭次信息");
                                                if (compareFlag == "min")
                                                    UpdateHistoryCourtNO(historyCourtDataNO, keyValuePair.Key, "-", lastresultmodelist,typedReference.Number);
                                                if (compareFlag == "max")
                                                    UpdateHistoryCourtNO(historyCourtDataNO, keyValuePair.Key, "+", lastresultmodelist, typedReference.Number);
                                            }
                                            compareResult = string.Empty;
                                            break;
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }
                                }
                                lastCourtNO = keyValuePair.Key;
                            }
                            // 比对后发现本次开庭时间时最小或是最大，计算庭次
                            if (compareResult == "max")
                            {
                                re = "N:" + Convert.ToString(Convert.ToInt32(lastCourtNO) + 1);
                                dataContext.InteractiveShow.LogShow("当前的开庭时间最大，推导出新的新的庭次" + re);
                            }
                            if (compareResult == "min")
                            {
                                if (Convert.ToString(Convert.ToInt32(lastCourtNO) - 1) == "0")
                                {
                                    re = "N:1";
                                }
                                else
                                {
                                    re = "N:" + Convert.ToString(Convert.ToInt32(lastCourtNO) - 1);
                                }
                                // 如果当前的开庭日期是最小的，需要看看数据库中排序后的第一条开庭次数是多少，如果第一条的开庭次数为1
                                // 那么需要将数据库所有的开庭次数都减1，如果第一条的开庭次数大于1，那么就不需要更新数据库中记录的开庭庭次
                                dataContext.InteractiveShow.LogShow("当前的开庭时间最小，推导出新的新的庭次为1。");
                                if (firstCourtNo == "1")
                                {
                                    UpdateHistoryCourtNO(historyCourtDataNO, firstCourtNo, "+", lastresultmodelist,typedReference.Number);
                                }
                            }
                        }
                    }
                    else
                    {
                        // 无用的文书
                        dataContext.InteractiveShow.LogShow("当前文本未提取到的开庭时间。");
                        re = "U:";
                    }
                }
                else
                {
                    // 已经提取传来了庭次
                    re = "E:" + courtNo;
                }
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("CourtNoDeduce:DeduceCourtNo 报错" + ex.ToString(), LogMessageType.Error);
            }
            return re;
        }



        private Dictionary<string, Tuple<string, string>> GetHistoryCourtDateNO(string caseOnlyID,out List<DataModel> LastResultModelList, TtargetDataConfig typedReference)
        {
            LastResultModelList = new List<DataModel>();
            DataResultSave dataResultSave = new DataResultSave(dataContext);
            DAL_An_anjiancunchu anjiancunchudal = new DAL_An_anjiancunchu();
            Dictionary<string, Tuple<string, string>> courtDateValuesOrdered = new Dictionary<string, Tuple<string, string>>();
            Dictionary<string, Tuple<string, string>> courtNODate = new Dictionary<string, Tuple<string, string>>();
            var dataTable = anjiancunchudal.GetList(caseOnlyID, "3");
            foreach (var dr in dataTable)
            {
                string fid = dr.Wenjianid;
                DataSoursModel dataSoursModel = GetDataSoursModel(dataResultSave.ReadDataXML(fid));
                LastResultModelList = dataSoursModel.dataModelList;
                DataModel dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataSoursModel.dataModelList, "", typedReference.Xmlpath);
                if (dataModel != null)
                {
                    if (dataModel.AttributesList.FirstOrDefault(a => a.Name == typedReference.Number) != null)
                    {
                        string courtNO = dataModel.AttributesList.FirstOrDefault(a => a.Name == typedReference.Number).sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;

                        if (dataModel.AttributesList.FirstOrDefault(a => a.Name == typedReference.OpeningTime) != null)
                        {
                            courtNODate[courtNO] = new Tuple<string, string>(dataModel.ID, dataModel.AttributesList.FirstOrDefault(a => a.Name == typedReference.OpeningTime).sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue);
                        }
                        else
                        {
                            if (!courtNODate.ContainsKey(courtNO))
                            {
                                courtNODate[courtNO] = new Tuple<string, string>(dataModel.ID, "");
                            }
                        }
                    }
                }
                if (courtNODate.Count() > 0)
                {
                    courtDateValuesOrdered = courtNODate.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
                }
            }
            return courtDateValuesOrdered;
        }

        /// <summary>
        /// 更新数据库中的庭次
        /// </summary>
        /// <param name="historyCourtNO">数据库中的庭次列表《庭次,EDID:开庭时间》</param>
        /// <param name="key">键值，该键值之后的庭次进行修改</param>
        /// <param name="updateFun">修改方法 +加1 -减1</param>
        private void UpdateHistoryCourtNO(Dictionary<string, Tuple<string, string>> historyCourtNO, string key, string updateFun,List<DataModel> lastResultModelList,string attName)
        {
            int keyIndex = 0;
            int loop = 0;
            try
            {
                foreach (var item in historyCourtNO)
                {
                    loop++;
                    if (item.Key != key)
                        keyIndex++;
                    if (loop > keyIndex)
                    {
                        string newCourtNO = string.Empty;
                        // 获取EDID
                        //string edID = item.Value.Split(':')[0];
                        string edID = item.Value.Item1;
                        if (updateFun == "+")
                            newCourtNO = Convert.ToString(Convert.ToInt32(item.Key) + 1);
                        if (updateFun == "-")
                            newCourtNO = Convert.ToString(Convert.ToInt32(item.Key) - 1);

                        // 更新庭次
                        DataModel dataModel = lastResultModelList.FirstOrDefault(a => a.ID == edID);
                        if (dataModel != null)
                        {
                            dataModel.AttributesList.FirstOrDefault(a => a.Name == "庭次").sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue = newCourtNO;
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("CourtNoDeduce:UpdateHistoryCourtNO 报错" + ex.ToString(), LogMessageType.Error);
            }
        }

        /// <summary>
        /// 转换出数据源实体
        /// </summary>
        /// <returns></returns>
        public DataSoursModel GetDataSoursModel(XmlDocument xmlDocument)
        {
            DataSoursModel soursModel = new DataSoursModel();
            soursModel = XmlUtility.DeserializeToObject<DataSoursModel>(xmlDocument.OuterXml.Replace("&#x", ""));
            foreach (DataModel dataModel in soursModel.dataModelList)
            {
                dataModel.XmlPath = dataModel.XmlPath.Replace("\\", "/");
            }
            return soursModel;
        }
    }
}
